# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider


class AmazonSpider(RedisCrawlSpider):
    name = 'amazon'
    allowed_domains = ['amazon.cn']
    # start_urls = ['https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/b/ref=topnav_storetab_b?ie=UTF8&node=658390051']
    redis_key = "amazon"

    rules = (
        # Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),

        # 匹配大分类的url地址和小分类的url地址
        Rule(LinkExtractor(restrict_xpaths=('//h4[@class="a-size-small a-color-base a-text-bold"]/../../following-sibling::ul[1]/div/li',)), follow=True),
        # 匹配图书的url地址
        Rule(LinkExtractor(restrict_xpaths=('//div[@id="mainResults"]/ul/li//h2/..')),callback='parse_book_detail'),
        # 列表页翻页
        Rule(LinkExtractor(restrict_xpaths=('//a[@title="下一页"]',)), follow=True),

    )

    #在详情页提取数据
    def parse_book_detail(self,response):
        item = {}
        item["url"] = response.url
        item["name"] = response.xpath('//span[@id="ebooksProductTitle"]/text()').extract_first().strip()
        item["author"] = response.xpath('//span[@class="author notFaded"]//text()').extract()
        item["author"]= [i.strip() for i in item["author"] if len(i.strip()) > 0]
        #2018年初源代码中图片是经过base64加密的（存储图片的方法值得借鉴），现在直接放的是链接
        item["img"] = response.xpath('//div[@id="ebooks-img-canvas"]/img/@src').extract_first()
        item["price"] = response.xpath('//span[@class="a-color-base"]/span/text()').extract_first().strip()
        item["cate"] = response.xpath('//div[@id="wayfinding-breadcrumbs_feature_div"]/ul/li[not(@class)]/span/a/text()').extract()
        item["cate"] = [i.strip() for i in item["cate"] if len(i.strip()) > 0]
        item["press"] =response.xpath('//b[text()="出版社:"]/../text()').extract_first()
        #描述参考老师的代码，源文件跟Elements不一致
        # item["desc"] = response.xpath('//noscript/div/text()').extract()  这个也可以！
        item["desc"] = response.xpath('//div[@id="postBodyPS"]/div/text()').extract()
        item["desc"] = [i.strip() for i in item["desc"] if len(i.strip())>0 and i!='海报：']
        print(item)


    #直接在列表页提取信息
    # def parse_item(self, response):
    #     item = {}
    #     li_list =response.xpath('//div[@id="mainResults"]/ul/li')
    #     for li in li_list:
    #         item["book_list_url"] = response.url
    #         item["name"] = li.xpath('.//h2/text()').extract_first()
    #         item["img"] = li.xpath('.//img/@src').extract_first()
    #         item["publish_date"] = li.xpath('.//div[@class="a-row a-spacing-small"]/div[1]/span[last()]/text()').extract_first()
    #         item["author"] = li.xpath('.//div[@class="a-row a-spacing-small"]/div[last()]//text()').extract()
    #         item["price"] = li.xpath('.//span[@class="a-size-base a-color-price s-price a-text-bold"]/text()').extract_first()
    #         print(item)


"""
注意1：
    在rules中包含一个或多个Rule对象，每个Rule对爬取网站的动作定义了特定操作。
    如果多个rule匹配了相同的链接，则根据规则在本集合中被定义的顺序，第一个会被使用（多个Rule的书写顺序值得注意）
注意2：
    follow：是一个布尔(boolean)值，指定了根据该规则从response提取的链接是否需要跟进。 
    （！！！）如果callback为None，follow 默认设置为True ，否则默认为False。
总结：多个Rule匹配相同的链接，第一个会被使用，重点来了：
    （1）该Rule中follow=True,该response中提取的链接构造request之后的response会直接进行下一轮for循环，重新从第一个Rule开始匹配（跟进）；而该response不会继续匹配下一个Rule
    尚不清楚：
        到底是该response本来就会依顺序遍历所有Rule，可匹配的Rule都会被使用（执行）
        还是只有在follow=False的情况下，该response才会匹配下一个Rule
    但是可以确定：下一个Rule一定会被执行，不然不可能获取翻页数据
    （2）（？？？？）该Rule中follow=False,该response会接着匹配的后面的Rule
---------------   ---------------   ---------------   ---------------   ---------------   ---------------   ---------------    
注意3：
    extract_first()，换行符、逗号、分号……会作为分隔符，谨慎使用！！(有错误)
    在一对引号内，分号不会作为作为分隔符
注意4：redis命令
    lpush amazon 'https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/b/ref=topnav_storetab_b?ie=UTF8&node=658390051'
    
    
"""
